package com.itheima.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableMap;
import com.itheima.wms.common.constants.CodeConstant;
import com.itheima.wms.common.enums.ReceiptStatus;
import com.itheima.wms.common.enums.ReceivingStatus;
import com.itheima.wms.common.service.CrudServiceImpl;
import com.itheima.wms.dao.*;
import com.itheima.wms.entity.*;
import com.itheima.wms.factory.CodeWorker;
import com.itheima.wms.service.IncreaseDecreaseService;
import com.itheima.wms.service.ReceiptListService;
import com.itheima.wms.service.ReceiptService;
import com.itheima.wms.service.StatusRecordService;
import com.itheima.wms.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 业务实现类
 * 入库单
 * </p>
 */
@Slf4j
@Service
public class ReceiptServiceImpl extends CrudServiceImpl<ReceiptMapper, ReceiptEntity> implements ReceiptService {

    @Autowired
    private OwnerMapper ownerMapper;
    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    private AreaMapper areaMapper;
    @Autowired
    private ReceivingMapper receivingMapper;
    @Autowired
    private GroundingMapper groundingMapper;
    @Autowired
    private CarrierMapper carrierMapper;

    @Autowired
    private StatusRecordService statusRecordService;
    @Autowired
    private ReceiptListMapper receiptListMapper;
    @Autowired
    private ReceiptListService receiptListService;
    @Autowired
    private IncreaseDecreaseService increaseDecreaseService;

    @Override
    public List<ReceiptVO> convertDetailList(List<ReceiptEntity> records) {
        return records.stream().map(item -> convertDetail(item)).collect(Collectors.toList());
    }

    @Override
    public ReceiptVO convertDetail(ReceiptEntity entity) {
        ReceiptVO receiptVO = new ReceiptVO();
        BeanUtils.copyProperties(entity, receiptVO);
        OwnerEntity ownerEntity = ownerMapper.selectById(receiptVO.getOwnerId());
        receiptVO.setOwnerName(ownerEntity.getName());
        receiptVO.setOwnerCode(ownerEntity.getCode());
        WarehouseEntity warehouseEntity = warehouseMapper.selectById(receiptVO.getWarehouseId());
        receiptVO.setWarehouseName(warehouseEntity.getName());
        AreaEntity areaEntity = areaMapper.selectById(receiptVO.getAreaId());
        receiptVO.setAreaName(areaEntity.getName());
        return receiptVO;
    }

    @Override
    public boolean save(ReceiptEntity entity) {
        boolean result = super.save(entity);
        ReceiptEntity dbEntity = this.getById(entity.getId());
        statusRecordService.saveStatus(dbEntity);
        return result;
    }

    @Override
    @Transactional
    public BatchVO receiving(List<Long> ids) {
        BatchVO.BatchVOBuilder batchVOBuilder = BatchVO.builder();
        ids.forEach(id -> {
            ReceiptEntity receiptEntity = this.getById(id);
            if (null == receiptEntity) {
                log.info("id:{} 未找到", id);
                return;
            }

            // 校验清单是否有未填写的
            LambdaQueryWrapper<ReceiptListEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ReceiptListEntity::getMasterId, id);
            List<ReceiptListEntity> receiptListEntities = receiptListMapper.selectList(wrapper);
            receiptListEntities = receiptListEntities.stream().filter(item -> (null != item.getPlanNum() && 0 != item.getPlanNum())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(receiptListEntities)) {
                log.info("id:{} 清单未填写完成", id);
                batchVOBuilder.error(receiptEntity.getCode() + "未完成货品清单");
                return;
            }

            if (ReceiptStatus.NEW.getCode() != receiptEntity.getStatus()) {
                log.info("id:{} 状态不正确", id);
                batchVOBuilder.error(receiptEntity.getCode() + "状态不合法");
                return;
            }

            LambdaQueryWrapper<ReceivingEntity> receivingWrapper = new LambdaQueryWrapper<>();
            receivingWrapper.eq(ReceivingEntity::getMasterId, receiptEntity.getId());
            Integer receivingCount = receivingMapper.selectCount(receivingWrapper);
            if (receivingCount > 0) {
                log.info("id:{} 已存在收货任务", id);
                batchVOBuilder.error(receiptEntity.getCode() + "已生成过收货任务");
                return;
            }

            // 修改入库单状态为  收货中
            receiptEntity.setStatus(ReceiptStatus.RECEIVING.getCode());
            this.updateById(receiptEntity);
            statusRecordService.saveStatus(receiptEntity);

            // 生成收货任务
            ReceivingEntity receivingEntity = new ReceivingEntity();
            BeanUtils.copyProperties(receiptEntity, receivingEntity);
            receivingEntity.setMasterId(receiptEntity.getId());
            receivingEntity.setCode(CodeWorker.nextCode(CodeConstant.RECEIVING));
            receivingEntity.setReceiptCode(receiptEntity.getCode());
            receivingEntity.setStatus(ReceivingStatus.NEW.getCode());  //初始状态
            receivingEntity.setId(null);
            receivingMapper.insert(receivingEntity);
            statusRecordService.saveStatus(receivingEntity);

            batchVOBuilder.result(receivingEntity.getCode());

        });
        return batchVOBuilder.build();
    }

    /**
     * 入库单详情
     *
     * @param id
     * @return 基础信息
     */
    @Override
    public ReceiptDetailVO getDetail(Long id) {
        ReceiptDetailVO receiptDetailVO = new ReceiptDetailVO();
        ReceiptEntity receiptEntity = this.getById(id);
        BeanUtils.copyProperties(receiptEntity, receiptDetailVO);

        LambdaQueryWrapper<ReceivingEntity> receivingWrapper = new LambdaQueryWrapper<>();
        receivingWrapper.eq(ReceivingEntity::getMasterId, id);
        ReceivingEntity receivingEntity = receivingMapper.selectOne(receivingWrapper);
        receiptDetailVO.setReceivingEntity(receivingEntity);

        LambdaQueryWrapper<GroundingEntity> groundingWrapper = new LambdaQueryWrapper<>();
        groundingWrapper.eq(GroundingEntity::getMasterId, id);
        GroundingEntity groundingEntity = groundingMapper.selectOne(groundingWrapper);
        receiptDetailVO.setGroundingEntity(groundingEntity);

        // 构建状态时间
        List<String> timeArray = statusRecordService.listTime(receiptEntity.getId());
        receiptDetailVO.setTimeArray(timeArray);
        // 仓库名称
        WarehouseEntity warehouseEntity = warehouseMapper.selectById(receiptEntity.getWarehouseId());
        receiptDetailVO.setWarehouseName(warehouseEntity == null ? String.valueOf(receiptEntity.getWarehouseId()) : warehouseEntity.getName());
        // 库区名称
        AreaEntity areaEntity = areaMapper.selectById(receiptEntity.getAreaId());
        receiptDetailVO.setAreaName(areaEntity == null ? String.valueOf(receiptEntity.getAreaId()) : areaEntity.getName());

        // 货主信息
        receiptDetailVO.setOwner(ownerMapper.selectById(receiptEntity.getOwnerId()));
        // 承运商名称
        receiptDetailVO.setCarrierName(carrierMapper.selectById(receiptEntity.getCarrierId()).getName());
        // 货品信息详情
        ReceiptListSumVO receiptListSumVO = receiptListMapper.sumReceiptListDetail(ImmutableMap.of("masterId", receiptEntity.getId()));
        receiptDetailVO.setGoodsTotal(receiptListSumVO.getGoodsTotal());
        receiptDetailVO.setVolumeTotal(receiptListSumVO.getVolumeTotal());

        // 损益
        if (null != groundingEntity) {
            List<IncreaseDecreaseDetailVO> increaseDecreaseEntities = increaseDecreaseService.listDetail(ImmutableMap.of("taskCode", groundingEntity.getCode()));
            if (!CollectionUtils.isEmpty(increaseDecreaseEntities)) {
                receiptDetailVO.setIdMoney(increaseDecreaseEntities.stream().filter(item -> item.getIdMoney() != null).map(IncreaseDecreaseEntity::getIdMoney).reduce(BigDecimal.ZERO, BigDecimal::add));
                receiptDetailVO.setIdList(increaseDecreaseEntities);
            }
        }
        return receiptDetailVO;
    }

    @Override
    public IPage<ReceiptDetailVO> pageDetail(Page<ReceiptDetailVO> page, Map data) {
        IPage<ReceiptDetailVO> iPage = this.baseMapper.selectReceiptDetail(page, data);
        return iPage;
    }
}

